package com.gzhryc.jdbc;

import com.gzhryc.jdbc.annotaion.Column;
import com.gzhryc.jdbc.annotaion.Id;
import com.gzhryc.jdbc.annotaion.PrimaryKey;
import com.gzhryc.jdbc.models.Parameters;
import com.gzhryc.jdbc.proxy.ModelProxy;
import com.gzhryc.jdbc.utils.EntityUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * 基础数据访问接口，提供常用的几个数据访问方法
 *
 * @param <T>
 * @author 张浩
 * @version 1.0.1
 * @param <T>
 */
public class BaseDao<T> extends JoinSelectDao<T> {

	public BaseDao() {
		this(null);
	}

	public BaseDao(String jdbcKey) {
		super(jdbcKey);
	}

	public String getJdbcKey() {
		return jdbcHelper.getJdbcKey();
	}

	/**
	 * 查询全部数据
	 *
	 * @return
	 * @throws SQLException
	 */
	public List<T> findAll() throws SQLException {
		return this.jdbcHelper.find("SELECT " + this.getSelectSQLFields().toString() + " FROM " + this.tableName,clazz);
	}

	public List<T> findByCondition(Conditions condition) throws SQLException {
		Query query = new Query("SELECT " + this.getSelectSQLFields().toString() + " FROM " + this.tableName);
		query.appendSql(condition.toSql(query.getParams(), true));
		return this.jdbcHelper.find(query, clazz);
	}

	/**
	 * 分页查询数据
	 *
	 * @param pageNo
	 * @param pageLimit
	 * @return
	 */
	public List<T> findAll(Integer pageNo, Integer pageLimit) throws SQLException {
		Query query = new Query("SELECT " + this.getSelectSQLFields().toString() + " FROM " + this.tableName);
		query.setPageNo(pageNo);
		query.setPageLimit(pageLimit);
		return this.jdbcHelper.find(query, clazz);
	}

	/**
	 * 分页查询数据
	 *
	 * @param condition
	 * @param pageNo
	 * @param pageLimit
	 * @return
	 * @throws SQLException
	 */
	public List<T> findByCondition(Conditions condition, Integer pageNo, Integer pageLimit) throws SQLException {
		Query query = new Query("SELECT " + this.getSelectSQLFields().toString() + " FROM " + this.tableName);
		query.appendSql(condition.toSql(query.getParams(), true));
		query.setPageNo(pageNo);
		query.setPageLimit(pageLimit);
		return this.jdbcHelper.find(query, clazz);
	}

	public List<T> findByConditionAndStartNum(Conditions condition, Long startNum, Integer pageLimit) throws SQLException {
		Query query = new Query("SELECT " + this.getSelectSQLFields().toString() + " FROM " + this.tableName);
		query.appendSql(condition.toSql(query.getParams(),true));
		query.setStartNum(startNum);
		query.setPageLimit(pageLimit);
		return this.jdbcHelper.find(query,clazz);
	}

	/**
	 * 统计数据的数量
	 *
	 * @return
	 * @throws SQLException
	 */
	public Long count() throws SQLException {
		Map<String, Object> result = this.jdbcHelper.get("select count(1) as TOTAL from " + tableName);
		return Long.valueOf(result.get("TOTAL").toString());
	}

	/**
	 * 有条件的统计数据的数量
	 *
	 * @param condition
	 * @return
	 * @throws SQLException
	 */
	public Long count(Conditions condition) throws SQLException {
		Query query = new Query("select count(1) as TOTAL from " + tableName);
		query.appendSql(condition.toSql(query.getParams(), true));
		Map<String, Object> result = this.jdbcHelper.get(query);
		return Long.valueOf(result.get("TOTAL").toString());
	}

	public T getById(Object id) throws SQLException {
		if (id != null && idField != null) {
			String idName = EntityUtils.getName(idField);
			Query query = new Query("SELECT " + this.getSelectSQLFields().toString()
					+ " FROM " + this.tableName + " WHERE " + idName + "=?");
			query.getParams().setObject(id);
			return this.jdbcHelper.get(query, clazz);
		} else {
			throw new SQLException("id is null");
		}
	}

	/**
	 * 根据条件获取一条数据
	 *
	 * @param condition
	 * @return
	 * @throws SQLException
	 */
	public T get(Conditions condition) throws SQLException {
		Query query = new Query("SELECT " + this.getSelectSQLFields().toString() + " FROM " + this.tableName);
		query.appendSql(condition.toSql(query.getParams(), true));
		return this.jdbcHelper.get(query, clazz);
	}

	public int insert(T obj) throws SQLException {
		return jdbcHelper.insert(this.tableName,obj);
	}

	public int insert(List<T> list) throws SQLException {
		return jdbcHelper.insert(this.tableName,clazz,list);
	}

	/**
	 * 全量修改
	 *
	 * @param obj
	 * @return
	 * @throws SQLException
	 */
	public int update(T obj) throws SQLException {
		if (obj instanceof ModelProxy) {
			return updateModelProxy((ModelProxy) obj);
		}
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			String sql = "update " + tableName + " set ";
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				// 只支持Column注释的属性
				Column column = field.getAnnotation(Column.class);
				if (column != null && !column.autoUpdateTime()) {
					if (idField != null && field.getName().equals(idField.getName())) {
						continue;
					}
					Object value = field.get(obj);
					String name = EntityUtils.getName(field);
					if (value != null) {
						sb.append(",").append(name).append("=?");
						params.setField(field, value);
					} else {
						sb.append(",").append(name).append("=null");
					}
				}
			}

			String name = EntityUtils.getName(idField);
			sql = sql + sb.substring(1) + " where " + name + "=?";
			params.setField(idField, idField.get(obj));
			return jdbcHelper.update(sql, params);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	/**
	 * 全量修改与Map的Key对应的字段
	 *
	 * @param data
	 * @return
	 * @throws SQLException
	 */
	public int update(Map<String, Object> data) throws SQLException {
		try {
			Object idValue = data.get(idField.getName());
			if (idValue == null) {
				return 0;
			}
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(clazz);
			String sql = "UPDATE " + tableName + " SET ";
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				// 只支持Column注释的属性
				if (field.isAnnotationPresent(Column.class)) {
					if (idField != null && field.getName().equals(idField.getName())) {
						continue;
					}
					// 检查是否存在
					if (data.containsKey(field.getName())) {
						Object value = data.get(field.getName());
						String name = EntityUtils.getName(field);
						if (value != null) {
							sb.append(",").append(name).append("= ?");
							params.setField(field, value);
						} else {
							sb.append(",").append(name).append("= null");
						}
					}
				}
			}
			String name = EntityUtils.getName(idField);
			sql = sql + sb.substring(1) + " WHERE " + name + "= ?";
			params.setField(idField, idValue);
			return jdbcHelper.update(sql, params);
		} catch (IllegalArgumentException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	public int update(Map<String, Object> data, Conditions condition) throws SQLException {
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(clazz);
			String sql = "UPDATE " + tableName + " SET ";
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				// 只支持Column注释的属性
				if (field.isAnnotationPresent(Column.class)) {
					if (idField != null && field.getName().equals(idField.getName())) {
						continue;
					}

					// 检查是否存在
					if (data.containsKey(field.getName())) {
						Object value = data.get(field.getName());
						String name = EntityUtils.getName(field);
						if (value != null) {
							sb.append(",").append(name).append("= ?");
							params.setField(field, value);
						} else {
							sb.append(",").append(name).append("= null");
						}
					}
				}
			}
			sql = sql + sb.substring(1) + condition.toSql(params, true);
			return jdbcHelper.update(sql, params);
		} catch (IllegalArgumentException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	public int update(T obj,Conditions condition) throws SQLException {
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(clazz);
			String sql = "UPDATE " + tableName + " SET ";
			StringBuilder fieldStr = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (idField != null && field.getName().equals(idField.getName())) {
					Id id = idField.getAnnotation(Id.class); // 如果自动生成则不进行修改
					if (id.auto()) {
						continue;
					}
				}
				String name = EntityUtils.getName(field);
				Object value = field.get(obj);
				if (value != null) {
					fieldStr.append(",").append(name).append("=?");
					params.setField(field, value);
				}else{
					fieldStr.append(",").append(name).append("=NULL");
				}
			}
			sql = sql + fieldStr.substring(1) + condition.toSql(params, true);
			return jdbcHelper.update(sql, params);
		}catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	/**
	 * 全量修改
	 *
	 * @param obj
	 * @param strings 忽略修改的字段
	 * @return
	 * @throws SQLException
	 */
	public int update(T obj, String... strings) throws SQLException {
		try {
			if (idField == null) {
				return 0;
			}
			Object idVal = idField.get(obj);
			if (idVal == null) {
				return 0;
			}

			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			String sql = "update " + tableName + " set ";
			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				// 只支持Column注释的属性
				Column column = field.getAnnotation(Column.class);
				if (column != null && !column.autoUpdateTime()) {
					if (field.getName().equals(idField.getName())) {
						continue;
					}
					boolean flag = true;
					for (String temp : strings) {
						if (temp.equals(field.getName())) {
							flag = false;
							break;
						}
					}
					if (flag) {
						Object value = field.get(obj);
						String name = EntityUtils.getName(field);
						if (value != null) {
							sb.append(",").append(name).append("=?");
							params.setField(field, value);
						} else {
							sb.append(",").append(name).append("=null");
						}
					}
				}
			}

			String name = EntityUtils.getName(idField);
			sql = sql + sb.substring(1) + " where " + name + "=?";
			params.setField(idField, idVal);
			return jdbcHelper.update(sql, params);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	/**
	 * 选择必须修改的字段
	 * 
	 * @param obj
	 * @param strings 必须修改的字段
	 * @return
	 * @throws SQLException
	 */
	public int updateNotNull(T obj, String... strings) throws SQLException {
		try {
			if (idField == null) {
				return 0;
			}
			Object idVal = idField.get(obj);
			if (idVal == null) {
				return 0;
			}

			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			String sql = "update " + tableName + " set ";

			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (field.getName().equals(idField.getName())) {
					continue;
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					sb.append(",").append(name).append("=?");
					params.setField(field, value);
				} else if (strings != null && strings.length > 0) {
					boolean flag = false;
					for (String temp : strings) {
						if (temp.equals(field.getName())) {
							flag = true;
							break;
						}
					}
					if (flag) {
						String name = EntityUtils.getName(field);
						sb.append(",").append(name).append("=NULL");
					}
				}
			}

			if (sb.length() > 1) {
				String name = EntityUtils.getName(idField);
				sql = sql + sb.substring(1) + " where " + name + "=?";
				params.setField(idField, idVal);
				return jdbcHelper.update(sql, params);
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
		return 0;
	}

	public int updateNotNull(T obj) throws SQLException {
		try {
			if (idField == null) {
				return 0;
			}
			Object idVal = idField.get(obj);
			if (idVal == null) {
				return 0;
			}
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			String sql = "UPDATE " + tableName + " SET ";

			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (field.getName().equals(idField.getName())) {
					continue;
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					sb.append(",").append(name).append("=?");
					params.setField(field, value);
				}
			}

			if (sb.length() > 1) {
				String name = EntityUtils.getName(idField);
				sql = sql + sb.substring(1) + " WHERE " + name + "=?";
				params.setField(idField, idVal);
				return jdbcHelper.update(sql, params);
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
		return 0;
	}

	public int updateNotNull(T obj, Conditions condition, String... strings) throws SQLException {
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			StringBuilder sql = new StringBuilder("update " + tableName + " set ");
			StringBuilder fieldStr = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (idField != null && field.getName().equals(idField.getName())) {
					Id id = idField.getAnnotation(Id.class); // 如果自动生成则不进行修改
					if (id.auto()) {
						continue;
					}
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					fieldStr.append(",").append(name).append("=?");
					params.setField(field, value);
				} else if (strings != null && strings.length > 0) {
					boolean flag = false;
					for (String temp : strings) {
						if (temp.equals(field.getName())) {
							flag = true;
							break;
						}
					}
					if (flag) {
						String name = EntityUtils.getName(field);
						fieldStr.append(",").append(name).append("=NULL");
					}
				}
			}

			sql.append(fieldStr.substring(1));
			sql.append(condition.toSql(params, true));
			return this.jdbcHelper.update(sql.toString(), params);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	public int updateNotNull(T obj, Conditions condition) throws SQLException {
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			StringBuilder sql = new StringBuilder("UPDATE " + tableName + " SET ");
			StringBuilder fieldStr = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (idField != null && field.getName().equals(idField.getName())) {
					Id id = idField.getAnnotation(Id.class); // 如果自动生成则不进行修改
					if (id.auto()) {
						continue;
					}
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					fieldStr.append(",").append(name).append("=?");
					params.setField(field, value);
				}
			}

			sql.append(fieldStr.substring(1));
			sql.append(condition.toSql(params, true));
			return this.jdbcHelper.update(sql.toString(), params);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	public int updateNotNullAndInc(T obj, Conditions condition,String... incFields) throws SQLException {
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			StringBuilder sql = new StringBuilder("update " + tableName + " set ");
			StringBuilder fieldStr = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (idField != null && field.getName().equals(idField.getName())) {
					Id id = idField.getAnnotation(Id.class); // 如果自动生成则不进行修改
					if (id.auto()) {
						continue;
					}
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					boolean flag = false;
					if(incFields != null && incFields.length > 0) {
						for (String temp : incFields) {
							if (temp.equals(field.getName())) {
								flag = true;
								break;
							}
						}
					}
					if (flag) {
						fieldStr.append(",").append(name).append("=").append(name).append("+ ?");
					}else{
						fieldStr.append(",").append(name).append("=?");
					}
					params.setField(field, value);
				}
			}

			if (fieldStr.length() > 0) {
				sql.append(fieldStr.substring(1));
			}
			sql.append(condition.toSql(params, true));
			return this.jdbcHelper.update(sql.toString(), params);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	public int updateNotNullAndInc(T obj, String... incFields) throws SQLException {
		try {
			if (idField == null) {
				return 0;
			}
			Object idVal = idField.get(obj);
			if (idVal == null) {
				return 0;
			}
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			String sql = "update " + tableName + " set ";

			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (field.getName().equals(idField.getName())) {
					continue;
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					boolean flag = false;
					if(incFields != null && incFields.length > 0) {
						for (String temp : incFields) {
							if (temp.equals(field.getName())) {
								flag = true;
								break;
							}
						}
					}
					if (flag) {
						sb.append(",").append(name).append("=").append(name).append("+ ?");
					}else{
						sb.append(",").append(name).append("=?");
					}
					params.setField(field, value);
				}
			}

			if (sb.length() > 1) {
				String name = EntityUtils.getName(idField);
				sql = sql + sb.substring(1) + " where " + name + "=?";
				params.setField(idField, idVal);
				return jdbcHelper.update(sql, params);
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
		return 0;
	}

	public int updateNotNullAndReduce(T obj, String... incFields) throws SQLException {
		try {
			if (idField == null) {
				return 0;
			}
			Object idVal = idField.get(obj);
			if (idVal == null) {
				return 0;
			}
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			String sql = "update " + tableName + " set ";

			StringBuilder sb = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (field.getName().equals(idField.getName())) {
					continue;
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					boolean flag = false;
					if(incFields != null && incFields.length > 0) {
						for (String temp : incFields) {
							if (temp.equals(field.getName())) {
								flag = true;
								break;
							}
						}
					}
					if (flag) {
						sb.append(",").append(name).append("=").append(name).append("- ?");
					}else{
						sb.append(",").append(name).append("=?");
					}
					params.setField(field, value);
				}
			}

			if (sb.length() > 1) {
				String name = EntityUtils.getName(idField);
				sql = sql + sb.substring(1) + " where " + name + "=?";
				params.setField(idField, idVal);
				return jdbcHelper.update(sql, params);
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
		return 0;
	}

	public int updateNotNullAndReduce(T obj, Conditions condition,String... incFields) throws SQLException {
		try {
			Parameters params = new Parameters();
			List<Field> fields = EntityUtils.findTableColumn(obj.getClass());
			StringBuilder sql = new StringBuilder("update " + tableName + " set ");
			StringBuilder fieldStr = new StringBuilder();
			for (int i = 0; i < fields.size(); i++) {
				Field field = fields.get(i);
				if (idField != null && field.getName().equals(idField.getName())) {
					Id id = idField.getAnnotation(Id.class); // 如果自动生成则不进行修改
					if (id.auto()) {
						continue;
					}
				}
				Object value = field.get(obj);
				if (value != null) {
					String name = EntityUtils.getName(field);
					boolean flag = false;
					if(incFields != null && incFields.length > 0) {
						for (String temp : incFields) {
							if (temp.equals(field.getName())) {
								flag = true;
								break;
							}
						}
					}
					if (flag) {
						fieldStr.append(",").append(name).append("=").append(name).append("- ?");
					}else{
						fieldStr.append(",").append(name).append("=?");
					}
					params.setField(field, value);
				}
			}

			if (fieldStr.length() > 0) {
				sql.append(fieldStr.substring(1));
			}
			sql.append(condition.toSql(params, true));
			return this.jdbcHelper.update(sql.toString(), params);
		} catch (IllegalArgumentException | IllegalAccessException e) {
			throw new SQLException(e.fillInStackTrace());
		}
	}

	/**
	 * 根据ID删除数据
	 *
	 * @param id
	 * @return
	 * @throws SQLException
	 */
	public int deleteById(Object id) throws SQLException {
		if (idField != null && id != null) {
			Parameters params = new Parameters();
			String idName = EntityUtils.getName(idField);
			String sql = "delete from " + tableName + " where " + idName + "=?";
			params.setField(idField, id);
			return jdbcHelper.update(sql, params);
		} else {
			throw new SQLException("ID is NULL OR is not table entity");
		}
	}

	/**
	 * 根据条件删除
	 *
	 * @param condition
	 * @return
	 * @throws SQLException
	 */
	public int deleteByCondition(Conditions condition) throws SQLException {
		Parameters params = new Parameters();
		return jdbcHelper.update("DELETE FROM " + tableName + condition.toSql(params, true), params);
	}

	public int deleteByJoinCondition(Conditions condition) throws SQLException {
		String alias = "t";
		StringBuffer sql = new StringBuffer("DELETE " + alias + " FROM " + tableName + " " + alias);
		String[] temp = this.buildJoinSql(alias);
		sql.append(temp[1]);
		Parameters params = new Parameters();
		sql.append(condition.toJoinSql(params, alias, true));
		return this.jdbcHelper.update(sql.toString(), params);
	}

	protected String buildFieldSql(String mainAlias) {
		List<Field> fields = EntityUtils.findTableColumn(this.clazz);
		StringBuilder fieldStr = new StringBuilder();
		if (this.idField != null) {
			Column column = idField.getAnnotation(Column.class);
			String name = idField.getName();
			if (column != null && StringUtils.isNotBlank(column.name())) {
				name = column.name();
			}
			if (StringUtils.isNotBlank(mainAlias)) {
				fieldStr.append(mainAlias).append(".").append(name);
			} else {
				fieldStr.append(name);
			}
		}
		for (int i = 0; i < fields.size(); i++) {
			Field field = fields.get(i);
			Column column = field.getAnnotation(Column.class);
			if (column != null) {
				if (idField != null && field.getName().equals(idField.getName())) {
					continue;
				}
				String name = column.name();
				if (StringUtils.isBlank(name)) {
					name = field.getName();
				}
				if (fieldStr.length() > 0) {
					fieldStr.append(",");
				}

				if (StringUtils.isNotBlank(mainAlias)) {
					fieldStr.append(mainAlias).append(".").append(name);
				} else {
					fieldStr.append(name);
				}
			}
		}
		return fieldStr.toString();
	}

	/**
	 * 获取查询语句的所有字段
	 * @return
	 */
	protected StringBuilder getSelectSQLFields(){
		List<Field> fields = EntityUtils.findTableColumn(this.clazz);
		StringBuilder sb = new StringBuilder();
		if (this.idField != null) {
			Column column = idField.getAnnotation(Column.class);
			String name = idField.getName();
			if (column != null && StringUtils.isNotBlank(column.name())) {
				name = column.name();
			}
			sb.append(name);
		}
		for (int i = 0; i < fields.size(); i++) {
			Field field = fields.get(i);
			Column column = field.getAnnotation(Column.class);
			if (column != null) {
				if (idField != null && field.getName().equals(idField.getName())) {
					continue;
				}
				String name = column.name();
				if (StringUtils.isBlank(name)) {
					name = field.getName();
				}
				if (sb.length() == 0) {
					sb.append(name);
				} else {
					sb.append(",").append(name);
				}
			}
		}
		return sb;
	}

	// 扩展方法

	public T get(String sql, Object... args) throws SQLException {
		Query query = new Query(sql);
		if (args != null) {
			for (Object obj : args) {
				query.getParams().setObject(obj);
			}
		}
		return jdbcHelper.get(query, clazz);
	}

	public List<T> find(String sql, Object... args) throws SQLException {
		Query query = new Query(sql);
		if (args != null) {
			for (Object obj : args) {
				query.getParams().setObject(obj);
			}
		}
		return jdbcHelper.find(query, clazz);
	}

	public <M extends ModelProxy> int updateModelProxy(M obj) throws SQLException {
		if (obj.getUpdateFields().size() > 0) {
			try {
				Parameters params = new Parameters();
				String sql = "update " + tableName + " set ";
				StringBuilder sb = new StringBuilder();
				for (String key : obj.getUpdateFields().keySet()) {
					Object value = obj.getUpdateFields().get(key);
					Field field = obj.getObjectClass().getDeclaredField(key);
					String name = EntityUtils.getName(field);
					if (value != null) {
						sb.append(",").append(name).append("=?");
						params.setField(field, value);
					} else {
						sb.append(",").append(name).append("= null");
						params.setField(field, null);
					}
				}

				String name = EntityUtils.getName(idField);
				sql = sql + sb.substring(1) + " where " + name + "=?";
				params.setField(idField, idField.get(obj));
				return jdbcHelper.update(sql, params);
			} catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
				throw new SQLException(e.fillInStackTrace());
			}
		}
		return 0;
	}

	public T warp(T obj) {
		return ModelProxy.create(obj).wrap();
	}
}
